import {
  number
} from './number.js'
import {
  strPad
} from './str.js'

// 一天的毫秒数
const _date_D = 86400000

// 标准格式化字符串
const _date_sf = 'yyyy-MM-dd HH:mm:ss'

// 格式化日期
const dateFormat = function(a, b) {
  if (typeof a === 'string')
    a = dateParse(a, b);
  let o = {
    y: a.getFullYear(),
    m: a.getMonth(),
    d: a.getDate(),
    h: a.getHours(),
    i: a.getMinutes(),
    s: a.getSeconds(),
  }
  let s = (b || _date_sf).replace('yyyy', o.y).replace('MM', strPad(o.m + 1)).replace('dd', strPad(o.d)).replace('HH',
      strPad(o.h))
    .replace('mm', strPad(o.i)).replace('ss', strPad(o.s))
    .replace('M', o.m + 1).replace('d', o.d).replace('H', o.h).replace('m', o.i).replace('s', o.s)
  if (s.indexOf('w') > -1) {
    let w = dateWeek(a)
    s = s.replace('ww', strPad(w[1])).replace('w', w[1])
  }
  return s
}

// 字串型转为日期型 /@a -> str, b -> format?
const dateParse = function(a, b) {
  a = ('' + a).replace(/\b(\d)\b/g, '0\$1');
  b = (b || _date_sf).replace(/\b([MdHmsw])\b/g, '\$1\$1');
  let c
  let y = (c = b.indexOf('yyyy')) > -1 ? (number(a.substr(c, 4)) || (new Date().getFullYear())) : (new Date()
    .getFullYear())
  let M = (c = b.indexOf('MM')) > -1 ? Math.max(number(a.substr(c, 2)) - 1, 0) : 0
  let d = (c = b.indexOf('dd')) > -1 ? number(a.substr(c, 2)) || 1 : 1
  let H = (c = b.indexOf('HH')) > -1 ? number(a.substr(c, 2)) : 0
  let m = (c = b.indexOf('mm')) > -1 ? number(a.substr(c, 2)) : 0
  let s = (c = b.indexOf('ss')) > -1 ? number(a.substr(c, 2)) : 0
  if ((c = b.indexOf('ww')) > -1) {
    let w = number(a.substr(c, 2))
    let t = dateWeek(new Date(y, 0, 1))
    if (t[0] != y)
      t = dateWeek(new Date(y, 0, 8))
    return new Date(t[2].getTime() + (w - 1) * 7 * _date_D)
  }
  return new Date(y, M, d, H, m, s)
}

// 日期增减  /@ a -> date, b -> type enum (y/M/d/H/m/s), c -> value
const dateAdd = function(a, b, c) {
  c = number(c)
  let e = new Date(a.getTime())
  if (b === 'y')
    e.setFullYear(a.getFullYear() + c)
  else if (b === 'M')
    e.setMonth(e.getMonth() + c)
  else if (b === 'd')
    e.setDate(e.getDate() + c)
  else if (b === 'H')
    e.setHours(e.getHours() + c)
  else if (b === 'm')
    e.setMinutes(e.getMinutes() + c)
  else if (b === 's')
    e.setSeconds(e.getSeconds() + c)
  if ((b === 'y' || b === 'M') && e.getDate() != a.getDate())
    e = new Date(e.getTime() - e.getDate() * _date_D)
  return e
}

// 取得一个日期对象的week相关信息。返回一个包含四个元素的数组，【 年份，第几周，周一的日期，周日的日期 】
// @a -> date
const dateWeek = function(a) {
  let b = $.x.weekPoint != null ? $.x.weekPoint : 1 //周的重心(星期几，从0到6)
  let c = $.x.weekStart != null ? $.x.weekStart : 1 //周的第一天(星期几，从0到6)
  let w = a.getDay() || 7
  let d = new Date(a.getFullYear(), a.getMonth(), a.getDate() - w + b)
  let e = Math.ceil((d - new Date(d.getFullYear(), 0, 0)) / _date_D)
  let f = new Date(a.getFullYear(), a.getMonth(), a.getDate() - w + c)
  return [d.getFullYear(), Math.floor((e + 6) / 7), f, new Date(f.getTime() + (7 * _date_D) - 1)]
}

// 获取某年的第一周
const dateWeekFirst = function(year) {
  let c = $.dateWeek(new Date(year, 0, 1))
  if (c[0] != year)
    c = $.dateWeek(new Date(year, 0, 8))
  return c
}

// 获取某年的最后一周
const dateWeekLast = function(year) {
  let b = dateWeek(new Date(year, 11, 31))
  if (b[0] !== year)
    b = dateWeek(new Date(year, 11, 31 - 7))
  return b
}

// 判断一个字符串格式的日期是否正确  /@ a -> date string, b -> date format string
const dateValid = function(a, b) {
  a = a.replace(/\b(\d)\b/g, '0$1')
  let d = dateParse(a, b)
  let y = d.getFullYear()
  return y >= 1000 && y <= 9999 && a == dateFormat(d, b)
}

const dateDiff = function(a, b = new Date, c) {
  if (typeof a === 'string') a = dateParse(a)
  if (typeof b === 'string') b = dateParse(b)
  switch (c) {
    case 'y':
      let e = b.getFullYear() - a.getFullYear()
      let f = dateAdd(a, c, e)
      if (f > b) e--
      return e
    case 'M':
      let y = _dateDiff(a, b, 'y')
      let z = dateAdd(a, 'y', y)
      e = z.getFullYear() < b.getFullYear() ? b.getMonth() + 11 - z.getMonth() : b.getMonth() - z.getMonth()
      f = dateAdd(a, c, e)
      if (f > b) e--
      return e + y * 12
    case 'H':
      return Math.floor((b - a) / (60 * 60 * 1000))
    case 'm':
      return Math.floor((b - a) / (60 * 1000))
    case 's':
      return Math.floor((b - a) / 1000)
    default: // 'd' 日期类型为默认
      return Math.floor((b - a) / _date_D)
  }
}

const dateSheet = function(...args) {
  return $.docView.dateSheet(...args)
}

export {
  dateFormat,
  dateParse,
  dateAdd,
  dateValid,
  dateDiff,
  dateSheet,
  dateWeek,
  dateWeekFirst,
  dateWeekLast,
}
